// IMPORT


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*IMPORT][IMPORT:1]]
import * as Sample from "./sample.module.js"
import * as Database from "./database.module.js"
import * as Json from "./json.module.js"
// IMPORT:1 ends here
// UTILITY


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*UTILITY][UTILITY:1]]
function mapc(object,fun){
    Object.keys(object).forEach(function(key){
        let value=object[key]
        fun(key,value)
    })
}
// UTILITY:1 ends here
// objectToHTML


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*objectToHTML][objectToHTML:1]]
let className="details"

function objectToHTML(object,element,title){

    formatA(element,aElementClassName)

    /* <div class="title"><p>方案</p><input type="text"></div> */
    formatTitle(element,title)

    formatFilter(undefined,element,filterElementClassName)

    formatConsole("程序加载成功",element,consoleElementClassName)

    formatToolbar(element,toolbarElementClassName)

    mapc(object,function(key,value){
        if(typeof(value)==="object"){
            formatDeatils(element,key,value,className)
        }else{
            formatPInput(element,key,value,className)
        }
    })

    return element
}

function getBoardElement(){
    return document.getElementById("board")
}
// objectToHTML:1 ends here
// formatTitle


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatTitle][formatTitle:1]]
let titleElementClassName="title"

function formatTitle(boardElement,title){
    formatPInput(boardElement,"方案",title||"当前方案",titleElementClassName)
}
function getTitleElement(){
    return document.querySelector("."+titleElementClassName)
}
function getTitleInputElement(){
    return getTitleElement().querySelector("input[type=text]")
}
function getTitle(){
    return getTitleInputElement().value
}
// formatTitle:1 ends here
// formatDetails


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatDetails][formatDetails:1]]
function formatDeatils(element,key,value,className){
    /* <details> */
    let details=document.createElement("details")

    /* <summary> */
    let summary=document.createElement("summary")
    summary.innerText=key
    details.appendChild(summary)

    /* <div class="details"> */
    formatPInputs(details,value,className)

    element.appendChild(details)

    return details
}
// formatDetails:1 ends here
// formatPInput


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatPInput][formatPInput:1]]
function formatPInputs(element,object,className,disabled,float){
    mapc(object,function(key,value){
        formatPInput(element,key,value,className,disabled,float)
    })
    return element
}

function formatPInput(element,key,value,className,disabled,float){
    /* <div class="details"> */
    let div=document.createElement("div")
    if(className){div.className=className}

    /* <p> */
    let p=document.createElement("p")
    p.innerText=key
    div.appendChild(p)

    /* <input> */
    let input=document.createElement("input")
    let type
    switch(typeof(value)){
        case "string":
            type="text"
            break
        case "number":
            type="number"
            break
    }
    input.type=type
    if(float&&type==="number"){
        value=parseFloat(value.toFixed(float))
    }
    input.value=value
    if(disabled){
        input.disabled="disabled"
    }
    div.appendChild(input)

    element.appendChild(div)

    return div
}
// formatPInput:1 ends here
// formatFilter


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatFilter][formatFilter:1]]
let filterElementClassName="filter"

function formatFilter(object,element,className,float){
    let filter=getFilterElement()
    if(filter===null){
        let div=document.createElement("div")
        div.className=className
        filter=div
        element.appendChild(div)
    }
    if(object){
        filter.innerHTML=""
        formatPInputs(filter,object,undefined,true,float)
    }
}

function getFilterElement(){
    return document.querySelector("."+filterElementClassName)
}
// formatFilter:1 ends here
// formatA


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatA][formatA:1]]
let aElementClassName="link"

function formatA(element,className){
    let div=document.createElement("div")

    if(className){
        div.className=className
    }

    let as=[{innerText:"反馈",
             href:"https://gitee.com/SunDawning/legate/issues/",
             title:"联系我，建议、问题，有空会慢慢处理的"},
            {innerText:"教程",
             href:"https://tieba.baidu.com/p/6848804364"},
            {innerText:"在线",
             href:"https://sundawning.gitee.io/legate/legate.html"},
            {innerText:"卖号",
             href:"https://lh.cbg.163.com/cgi/mweb/equip/9/202008072102616-9-AZWWB9BCTKFW6S",
             title:"2000RMB出号，可小刀"},
            {innerText:"卖金",
             href:"https://m.jiaoyimao.com/goods/1582013753168179.html",
             title:"1:4000，泡沫之里，出大额手工粮"}]
    as.forEach(function(object){
        let a=document.createElement("a")
        a.href=object.href
        let innerText=object.innerText
        if(!innerText){
            innerText=href
        }
        if(object.title){
            a.title=object.title
        }
        a.innerText=innerText
        a.target="_blank"
        div.appendChild(a)
    })

    element.appendChild(div)
}

function getAElement(){
    return document.querySelector("."+"aElementClassName")
}
// formatA:1 ends here
// formatToolbar


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatToolbar][formatToolbar:1]]
let toolbarElementClassName="toolBar"

function formatToolbar(element,className){
    let div=document.createElement("div")

    if(className){
        div.className=className
    }
    let buttons=[
        {innerText:"保存",
         title:"保存当前方案，便于切换方案，程序会每隔一段时间自动保存一套方案到＂自动存档＂",
         onclick:function(event){
             let titleElement=getTitleInputElement()
             if(titleElement.value==="基础方案"){
                 message("基础方案是默认方案，无法手动保存")
             }else{
                 Database.saveToRam(
                     board(titleElement,element))
                 formatSelectOptions(element,div)
                 message("已保存方案＂"+titleElement.value+"＂")
             }}},
        {innerText:"删除",
         title:"删除当前方案，如果存在的话，不存在则不删除",
         onclick:function(event){
             let titleElement=getTitleInputElement()
             if(titleElement.value==="基础方案"){
                 message("基础方案是默认方案，无法手动删除")
             }else{
                 Database.deleteOptionsByTitle(titleElement.value)
                 switchToOptions(element,0)
                 message("已删除方案＂"+titleElement.value+"＂")
             }}},
        {innerText:"清空",
         title:"此操作将清空所有个人数据，恢复到出厂设置，刷新页面后将不显示任何个人数据",
         onclick:function(event){
             Database.init()
             reload(element)
             message("已清空")}},
        {innerText:"设为对比",
         title:"将当前方案设置为对比方案，这样刷新页面后将在此基础上继续修改，对比数据",
         onclick:function(event){
             let titleElement=getTitleInputElement()
             setComparisonOptions(element,titleElement)
             message("已将方案＂"+titleElement.value+"＂设置为对比方案")
         }}
    ]
    buttons.forEach(function(object){
        let button=document.createElement("button")
        button.innerText=object.innerText
        button.onclick=object.onclick
        button.title=object.title
        div.appendChild(button)
    })

    formatSelectOptions(element,div)

    element.appendChild(div)
}

function getToolbarElement(){
    return document.querySelector("."+toolbarElementClassName)
}
// formatToolbar:1 ends here
// formatConsole


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatConsole][formatConsole:1]]
let consoleElementClassName="console"

function formatConsole(object,element,className){
    let console=getConsoleElement()
    if(console===null){
        let div=document.createElement("div")
        div.className=className
        console=div
        element.appendChild(div)
    }
    if(object){
        log(console,object)
    }
}
function getConsoleElement(){
    return document.querySelector("."+consoleElementClassName)
}
function message(object){
    let console=getConsoleElement()
    log(console,object)
}
function log(element,object){
    console.log(object)
    if(element!==null){
        let div=document.createElement("div")
        div.innerText=string(object)
        element.appendChild(div)
        element.scrollTop=element.scrollHeight
    }
}
function string(object){
    switch(typeof(object)){
        case "string":
            return object
        default:
            return Json.string(object)
    }
}
// formatConsole:1 ends here
// formatSelectOptions


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*formatSelectOptions][formatSelectOptions:1]]
function formatSelectOptions(board,div){
    let options=Database.localStorageGet("Database.options")
    if(options){
        let select=getSelectOptionsElement()
        if(select===null){
            select=document.createElement("select")
        }else{
            select.innerText=""
        }
        let option=document.createElement("option")
        let title="切换方案"
        option.innerText=title
        select.appendChild(option)

        options.forEach(function(object){
            let option=document.createElement("option")
            option.innerText=object.标题
            select.appendChild(option)
        })
        select.title="把当前方案切换为某个方案，可以是自动保存的，也可以是手动保存的方案"
        select.onchange=function(event){
            let index=select.selectedIndex
            if(index>0){
                message("当前方案已切换为方案＂"+switchToOptions(board,index-1).标题+"＂")
            }
        }
        div.appendChild(select)
    }
}

function getSelectOptionsElement(){
    return document.querySelector("select")
}

function switchToOptions(element,index){
    let consoleLog=getConsoleElement().innerHTML
    element.innerHTML=""
    let options=Database.localStorageGet("Database.options")[index]
    objectToHTML(options.方案,element,options.标题)
    getConsoleElement().innerHTML=consoleLog
    let objects=Sample.report([
        Sample.option(Database.localStorageGet("Database.optionsName")||"基础方案",Sample.copyOptions()),
        options
    ])
    formatFilter(Sample.filter(objects[1]),element,"filter",4)
    return options
}

function reload(element){
    let options=Sample.copyOptions()
    Database.setDefaultOptions(options)
    Database.saveToRam(Sample.option("基础方案",options))
    switchToOptions(element,0)
}
// formatSelectOptions:1 ends here
// setComparisonOptions


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*setComparisonOptions][setComparisonOptions:1]]
function setComparisonOptions(boardElement,titleElement){
    let options=HTMLToObject(boardElement)
    Database.setDefaultOptions(options)
    Database.localStorageSet("Database.optionsName",titleElement.value)
    let option=Sample.option(titleElement.value,options)
    let objects=Sample.report([option,option])
    formatFilter(Sample.filter(objects[1]),boardElement,"filter",4)
}
// setComparisonOptions:1 ends here
// board

// 从网页里收集包含标题和方案的内容


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*board][board:1]]
function board(titleElement,boardElement){
    return Sample.option(
        titleElement.value,
        HTMLToObject(boardElement))
}
// board:1 ends here
// HTMLToObject


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*HTMLToObject][HTMLToObject:1]]
function HTMLToObject(board){
    return arrayToObject(parseBoard(board,className))
}
// HTMLToObject:1 ends here
// arrayToObject


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*arrayToObject][arrayToObject:1]]
function arrayToObject(array){
    let options={}
    array.forEach(function(vector){
        let key=vector[0] // 暴击率
        let value=vector.slice(1)
        if(value.length===1){
            value=parseFloat(value[0]) // 传递系数:0
        }else{
            let object={}
            value.forEach(function(vector){
                let key=vector[0]
                let value=vector[1]
                let number=parseFloat(value)
                // 技能名称: "耀星"
                if(number.toString()!=="NaN"){
                    value=number
                }
                object[key]=value
            })
            value=object
        }
        options[key]=value
    })
    return options
}
// arrayToObject:1 ends here
// parseBoard

// #+BEGIN_EXAMPLE
// <div id="board">
//   <details>
//     <summary>无视抗性后巨兽受到的伤害</summary>
//     <div class="details">
//       <p>巨兽抗性星级</p>
//       <input type="number">
//     </div>
//   </details>
//   <div class="details">
//     <p>肉质系数</p>
//     <input type="number">
//   </div>
// </div>
// #+END_EXAMPLE


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*parseBoard][parseBoard:1]]
function parseBoard(board,className){
    let values=[]
    mapc(board.children,function(key,value){
        let name=value.nodeName
        switch(name){
            case "DETAILS":
                values.push(parseDetails(value,className))
                break
            case "DIV":
                let div=parsePInput(value,className)
                if(div){
                    values.push(div)
                }
                break
        }
    })
    return values
}
// parseBoard:1 ends here
// parseDetails

// #+BEGIN_EXAMPLE
// <details>
//   <summary>无视抗性后巨兽受到的伤害</summary>
//   <div class="details">
//     <p>巨兽抗性星级</p>
//     <input type="number">
//   </div>
// </details>
// #+END_EXAMPLE


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*parseDetails][parseDetails:1]]
function parseDetails(details,className){
    let values=[]
    mapc(details.children,function(key,value){
        let name=value.nodeName
        switch(name){
            case "SUMMARY":
                values.push(value.innerText)
                break
            case "DIV":
                values.push(parsePInput(value,className))
                break
        }
    })
    return values
}
// parseDetails:1 ends here
// parsePInput

// #+BEGIN_EXAMPLE
// <div class="details">
//   <p>巨兽抗性星级</p>
//   <input type="number">
// </div>
// #+END_EXAMPLE


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*parsePInput][parsePInput:1]]
function parsePInput(div,className){
    if(div.className===className){
        let values=[]
        mapc(div.children,function(key,value){
            let name=value.nodeName
            switch(name){
                case "P":
                    values.push(value.innerText)
                    break
                case "INPUT":
                    values.push(value.value)
                    break
            }
        })
        return values
    }
}
// parsePInput:1 ends here
// EXPORT


// [[file:~/literate-programming/soul-hunter-awakening-damage-calculator-web-edition.org::*EXPORT][EXPORT:1]]
export{objectToHTML,HTMLToObject,formatFilter,getTitle,getBoardElement}
// EXPORT:1 ends here
